クラスメソッドのReact事情大公開スペシャル -「長期運用に耐えるフロントエンド目指して」というテーマで登壇しました #クラスメソッド勉強会
先日、クラスメソッドのReact事情大公開スペシャルというイベントにて、「長期運用に耐えるフロントエンド目指して」というテーマで登壇しました。
登壇資料
登壇資料はこちらです。
フロントエンド開発、順調に進んでる?
会場でも来場者のみなさんに軽く聞いてみましたが、首を横に振られている方が多かったように思います。
(残念ながら私もNoです🥺)
なぜそんなに苦労しているのか、それはフロントエンドならではの難しさがあるからだと私は考えています。
一つは変化の激しさです。
Reactを例にとって考えてみると、直近では従来からあるSPA・クライアントサイドでのレンダリングが主流だったものからServer Componentが出てきたりして、関心がサーバーサイドに寄りつつあります。少し過去を振り返ってみると、他にも Suspense や React Hooks など色々あったように記憶しています。
こういった大きな変化が数年ごとに起きているように思いますし、その影響もあってか周辺ツールやエコシステムも変わっていきます。
(ただ、Reactに関してはいきなり後方互換を切ったりすることは少ない気がしています。)
次にフロントエンドの担当領域が広がっていることです。
一昔前はJSON色付け係と呼ばれることもあったフロントエンドエンジニアですが、今やそのタスクは見た目を整えることだけに留まりません。
チームによってはクリーンアーキテクチャのような設計をされる方もおられますし、CDN / BFF / GraphQL が関わるとインフラ・バックエンドも関わります。近年では A11yへの注目も高まりつつあります。
かつ、ユーザーが触れる部分になるので使い勝手やUXへのケアも必要です。
継続運用していくための工夫
ライブラリを直接参照しない
まず1つめは、ライブラリを直接参照することを避けることです。
まず前提として、フロントエンドはバックエンドでいうところの Rails や Laravel のような、いわゆるフルスタックフレームワークと呼ばれるものがまだまだメジャーではないと考えています。
そういうこともあり、多くの場合、たくさんのライブラリをかけあわせてアプリケーションを構成することになります。
開始時点ではイケてるライブラリを選定したつもりが、時を経てレガシーになることもしばしばです。
どんなライブラリもレガシー化することを頭の片隅に置いて、可能な限り交換可能な構成を目指すべきだと私は考えます。
scaffolding の活用
次に scaffolding の活用です。
弊チームでは基本的には手動でコンポーネントを作成することを避けるようにしています。
これはなるべく Test と Storybook を意識させたいという意図があります。
Test や Storybook をちゃんとメンテしていくとなるとファイル数が大きくなり、負荷が高くなりがちなので自動化できるところは自動化しています。
「Storyshots じゃダメなの?」という質問をいただきましたが、弊プロジェクトでは msw や Storybook の Play function 等を多用しており、スナップショットを取得するタイミングの制御が難しかったので 自前 + scaffolding に落ち着きました。副作用が少ないコンポーネントの単位になっているのであればStoryshotsでも事足りるのかなと思っています。
Renovate を使ったライブラリの定期更新
最後に Renovate を使ったライブラリの定期更新の話をしました。
繰り返しになりますが、フロントエンドは様々なライブラリに依存することが多いので、ライブラリのバージョン管理も大きなタスクの一つになります。
開発初期は最新のバージョンですが、リリース時には気づけばレガシーに片足突っ込んでいるなんてこともしばしばです。
必要になるまではバージョンアップをしないというプロジェクトも多いと思いますが、弊チームでは逆の考えで「特に理由がなければ新しいバージョンに追従していく」という方針を取っています。こういった雰囲気を醸成するのにも Renovate が貢献してくれています。
導入は難しくないのですが、デフォルトの設定だと CI の実行時間を大きく消費してしまったり、通知が大量に発生したりするので、プロジェクトに合う設定を調整しながら動かすことをおすすめします。
弊チームでは今のところ 2週間に1回程度のペースで稼働させています。
毎日対応する必要はないと思いますが、定期的に棚卸しをすることが大切です。
反省
ここまでで工夫している点についてお話してきました。
自分が経験してきたプロジェクトの中でも比較的良い形で進められているように感じていますが、後悔していることもあります。
それは UI コンポーネントライブラリを安易に採用しすぎたことです。
色々な考え方があると思いますが、ポイントは「安易に」というところです。
またまた繰り返しになりますが、多くのライブラリに依存することを前提とした場合、上記で言及した通り、レガシー化のリスクや交換可能性の問題が出てきます。
ですが、 UI コンポーネントライブラリに関しては新しいものが次々に出てくる上に、交換が不可能に近いです。
最近は Zero-Runtime CSS-in-JS といった技術も出てきつつありますが、そういったものに対応していないライブラリは Server Component として扱えないものも多いので、 Next.js を採用する場合は特に注意した方が良いでしょう。
また、ライブラリの組み合わせによっては相性が良くない場合もあります。
私の経験としては React Hook Form と組み合わせた際、 UI コンポーネント側の仕様に引っ張られて非制御コンポーネントとして実装することができず、結果的にパフォーマンスが劣化してしまい、ライブラリの良さを100%引き出せないという事象に出くわしました。
初速の速さやデザイナー不在でも形にできるという大きなメリットはありますが、長期運用を見据えた場合、こういったライブラリの交換可能性・組み合わせに関するリスク、将来的な要件の変更等に柔軟に対応することが困難になる可能性があるということを念頭に入れた上で、本当に採用するメリットの方が大きいのかしっかり検討すべきでしょう。
まとめ
最後にまとめです。
やることが多々あること、ライブラリ関連の話はすでにお話した通りです。
ライブラリも含めてフロントエンドの技術選定をする際、 RFC に目を通した上で、「このライブラリは RFC の方向性と合っているな」といった視点で技術選定できると一番良い気がしますし、1周回ってコスパの良い方法なのではないかと最近思い始めました。
RFC はハードルが高いと感じられる方は日本語の記事でも詳しく解説されているものがあったりします。
こういったものも含め、RFC や experimental な機能でも予め知っておくことで今後の方向性が見えやすくなる気がしています。
所感
発表後の懇親会でも色々な方と意見交換させていただきましたが、フロントエンドのプロジェクトについては十プロジェクト十色といった形で、ベストプラクティスがまだまだ確立されていないのかなーと感じました。
特にApp Router に関しては私も含めて苦労されている方が多そうで、移行は難しい、新規なら検討するかもといった方が多そうでした。
経験ベースで色々な話を聞けたことは非常に勉強になりましたし、最新技術の話で盛り上がれたのはとても楽しかったです。引き続きフロントエンド技術をキャッチアップしていきたいと思えました。
ご参加いただいた皆様、このような機会をくださった運営の皆様、本当にありがとうございました。